﻿using Hangfire;
using IGeekFan.AspNetCore.Knife4jUI;
using KAs.Application.Contract.Svc;
using KAs.Common.Const;
using KAs.Filter;
using KAs.StartUp;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace Microsoft.Extensions.DependencyInjection;

public static class StartUpExtensions
{
    public static void ConfigureServices(this IServiceCollection services, IConfiguration configuration, AppConfig appConfig = null)
    {
        appConfig ??= new AppConfig();

        // 注册所有服务
        services.AddAppServices();
        // 注册sqlsugar
        services.AddSqlSugarSetup(configuration);
        // 注册redis缓存
        if (appConfig.UseRedis)
            services.AddRedisDistributedCacheService(configuration);
        else
            services.AddMemoryCacheService();
        // 注册hangfire后台服务
        if (appConfig.UseHangfire)
            services.AddHangfireSetup(configuration);
        // 注册鉴权过滤器及异常过滤器
        services.Configure<MvcOptions>(opt =>
        {
            opt.Filters.Add<ApiAuthorFilter>();
            opt.Filters.Add<ActionFilter>();
            opt.Filters.Add<ExceptionFilter>();
        });
        services.AddControllers().AddJsonConverter();
        // 跨域配置
        services.AddCors(options =>
        {
            options.AddPolicy(ConstConfig.ANY_ALLOW, corsbuilder =>
            {
                var corsPath = configuration.GetSection("CorsPaths").GetChildren().Select(p => p.Value).ToArray();
                corsbuilder.WithOrigins(corsPath)
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials();//指定处理cookie
            });
        });
        // 添加Swagger，并获取各程序集生成xml文件，用于api注释
        // 生成xml需要在对应项目中，选择生成api文件，并建议取消1591的代码检测
        services.AddSwaggerGen();
        services.AddOptions<SwaggerGenOptions>()
            .Configure<IAssembliesService>((options, service) =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo
                {
                    Title = "西海岸",
                    Version = "v1",
                    Description = "西海岸飞盘",
                });
                foreach (var assemblyName in service.GetAssemblyNames())
                {
                    var xmlPath = Path.Combine(AppContext.BaseDirectory, $"{assemblyName}.xml");
                    if (File.Exists(xmlPath))
                        options.IncludeXmlComments(xmlPath);
                }
            });
    }

    public static void Configure(this IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider provider, AppConfig appConfig = null)
    {
        appConfig ??= new AppConfig();

        if (env.IsDevelopment() || appConfig.ShowSwaggerUI)
        {
            app.UseSwagger();
            app.UseKnife4UI(o =>
            {
                o.RoutePrefix = "";
                o.SwaggerEndpoint("/swagger/v1/swagger.json", "KAs.Frame v1");
            });
        }

        if (!env.IsDevelopment() && appConfig.UseHttpsRedirection)
        {
            app.UseHttpsRedirection();
        }

        app.UseRouting();
        // 使用跨域策略
        app.UseCors(ConstConfig.ANY_ALLOW);
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            // hangfire dashboard
            if (appConfig.UseHangfire)
                endpoints.MapHangfireDashboard();
        });
    }
}